package com.flow.framework.core.holder;

import com.flow.framework.common.constant.FrameworkCommonConstant;
import com.flow.framework.common.error.SystemErrorCode;
import com.flow.framework.common.exception.CheckedException;
import com.flow.framework.common.json.JsonObject;
import com.flow.framework.common.util.verify.VerifyUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * 用户操作日志参数上下文持有者
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2022/2/5
 */
@Slf4j
public class OptLogI18nContextHolder {

    private static final ThreadLocal<I18nContext> CONTEXT_HOLDER_CONTENT_CACHE_THREAD_LOCAL
            = ThreadLocal.withInitial(I18nContext::new);

    private static <T, R> R getValue(Function<I18nContext, R> callback) {
        I18nContext contextContent = CONTEXT_HOLDER_CONTENT_CACHE_THREAD_LOCAL.get();
        if (null == contextContent) {
            return null;
        }
        return callback.apply(contextContent);
    }

    private static <T> void setValue(T value, BiConsumer<I18nContext, T> callback) {
        I18nContext contextContent = CONTEXT_HOLDER_CONTENT_CACHE_THREAD_LOCAL.get();
        if (null == contextContent) {
            contextContent = new I18nContext();
            CONTEXT_HOLDER_CONTENT_CACHE_THREAD_LOCAL.set(contextContent);
        }
        callback.accept(contextContent, value);
    }

    /**
     * 获取操作日志参数字符串
     *
     * @return 空字符串或者json字符串
     */
    public static String getOptLogI18nParamString() {
        I18nContext i18nContext = CONTEXT_HOLDER_CONTENT_CACHE_THREAD_LOCAL.get();
        if (null == i18nContext) {
            log.error("i18n context is null.");
            throw new CheckedException(SystemErrorCode.OBJECT_NOT_FOUND_ERROR);
        }
        Object i18nParam = i18nContext.getI18nParam();
        if (null == i18nParam) {
            return FrameworkCommonConstant.EMPTY_STRING;
        }
        return JsonObject.toString(i18nContext);
    }

    /**
     * 操作是否成功
     *
     * @return 操作是否成功
     */
    public static boolean isSuccess() {
        return VerifyUtil.isTrue(getValue(I18nContext::getIsSuccess));
    }

    /**
     * 设置国际化参数
     *
     * @param i18nParam 国际化参数
     */
    public static void setI18nParam(Object i18nParam) {
        if (VerifyUtil.isEmpty(i18nParam)) {
            return;
        }
        setValue(i18nParam, I18nContext::setI18nParam);
    }

    /**
     * 设置是否成功
     *
     * @param isSuccess 是否成功
     */
    public static void setSuccess(boolean isSuccess) {
        setValue(isSuccess, I18nContext::setIsSuccess);
    }

    /**
     * 清空上下文缓存
     */
    public static void clear() {
        CONTEXT_HOLDER_CONTENT_CACHE_THREAD_LOCAL.remove();
    }


    /**
     * 国际化上下文缓存
     */
    @Data
    private static class I18nContext {

        /**
         * 国际化参数
         */
        private Object i18nParam;

        /**
         * 本次操作是否成功
         */
        private Boolean isSuccess = false;
    }
}
